﻿Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Controls
    <ToolboxData("<{0}:DropDownCalendar runat=server></{0}:DropDownCalendar>")> _
    Public Class DropDownCalendar
        Inherits WebControl

#Region "privatepro"
        Private _titleStyle As TableItemStyle
        Private _dayStyle As TableItemStyle
        Private _nextprevStyle As TableItemStyle
        Private _dayHeaderStyle As TableItemStyle
        Private _weekendDayStyle As TableItemStyle
        Private _dateStyle As TableItemStyle
        Private _buttonStyle As Style
#End Region

#Region "init"
        Public Sub New()
            _titleStyle = New TableItemStyle()
            _dayStyle = New TableItemStyle()
            _nextprevStyle = New TableItemStyle()
            _dayHeaderStyle = New TableItemStyle()
            _weekendDayStyle = New TableItemStyle()
            _dateStyle = New TableItemStyle()
            _buttonStyle = New Style()
        End Sub

        Protected Overloads Overrides Sub OnLoad(ByVal e As EventArgs)
            MyBase.OnLoad(e)
            If Page IsNot Nothing Then
                Dim cs As ClientScriptManager = Page.ClientScript
                Dim cstype As Type = Page.[GetType]()
                If Not cs.IsClientScriptBlockRegistered(cstype, key) Then
                    cs.RegisterClientScriptBlock(cstype, key, script, False)
                End If

                If Page.IsPostBack Then
                    Dim y As String = Page.Request.Form(ID + "_yeartext")
                    Dim m As String = Page.Request.Form(ID + "_monthtext")
                    Dim d As String = Page.Request.Form(ID + "_daytext")
                    Try
                        Value = DateTime.Parse(y + "-" + m + "-" + d)
                    Catch
                        Value = DateTime.Today
                    End Try
                End If
            End If
        End Sub
#End Region

#Region "styles"
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property TitleStyle() As TableItemStyle
            Get
                Return _titleStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property DayStyle() As TableItemStyle
            Get
                Return _dayStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property NextPrevStyle() As TableItemStyle
            Get
                Return _nextprevStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property DayHeaderStyle() As TableItemStyle
            Get
                Return _dayHeaderStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property WeekendDayStyle() As TableItemStyle
            Get
                Return _weekendDayStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property DateStyle() As TableItemStyle
            Get
                Return _dateStyle
            End Get
        End Property
        <Category("Styles"), PersistenceMode(PersistenceMode.InnerProperty)> _
        Public ReadOnly Property ButtonStyle() As Style
            Get
                Return _buttonStyle
            End Get
        End Property
#End Region

#Region "pro"
        <Category("Behavior"), DefaultValue(""), PersistenceMode(PersistenceMode.Attribute)> _
        Public Property Value() As DateTime
            Get
                Dim obj As Object = ViewState("Value")
                Return (IIf((obj Is Nothing), DateTime.Today, DirectCast(obj, DateTime)))
            End Get

            Set(ByVal value As DateTime)
                ViewState("Value") = value
            End Set
        End Property
#End Region

#Region "render"
        Public Overloads Overrides Sub RenderBeginTag(ByVal writer As HtmlTextWriter)
        End Sub
        Public Overloads Overrides Sub RenderEndTag(ByVal writer As HtmlTextWriter)
        End Sub
        Private Sub RenderSeparator(ByVal writer As HtmlTextWriter, ByVal s As String)
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "10%")
            writer.AddAttribute(HtmlTextWriterAttribute.Align, "center")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.Write(s)
            writer.RenderEndTag()
            'td 
        End Sub
        Private Sub RenderInput(ByVal writer As HtmlTextWriter, ByVal id As String, ByVal value As String)
            Dim val As String = IIf(value.Length = 1, "0" + value, value)
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "16%")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.AddAttribute(HtmlTextWriterAttribute.Id, id)
            writer.AddAttribute(HtmlTextWriterAttribute.Name, id)
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "none")
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0")
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, "transparent")
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text")
            writer.AddAttribute(HtmlTextWriterAttribute.Value, val)
            writer.AddAttribute(HtmlTextWriterAttribute.Onchange, "validate('" + Me.ID + "')")
            writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "center")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%")
            writer.RenderBeginTag(HtmlTextWriterTag.Input)
            writer.RenderEndTag()
            'Input 
            writer.RenderEndTag()
            'td 
        End Sub

        Protected Overloads Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
            Me.AddAttributesToRender(writer)
            If BorderStyle = BorderStyle.NotSet Then
                writer.AddStyleAttribute("border", "2px inset")
            End If
            If Width = Unit.Empty Then
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "1px")
            End If
            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0")
            writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0")
            writer.RenderBeginTag(HtmlTextWriterTag.Table)
            writer.RenderBeginTag(HtmlTextWriterTag.Tr)

            RenderInput(writer, ID + "_yeartext", Value.Year.ToString())
            RenderSeparator(writer, "年")
            RenderInput(writer, ID + "_monthtext", Value.Month.ToString())
            RenderSeparator(writer, "月")
            RenderInput(writer, ID + "_daytext", Value.Day.ToString())
            RenderSeparator(writer, "日")
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "20%")
            writer.AddAttribute(HtmlTextWriterAttribute.Align, "right")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            ButtonStyle.AddAttributesToRender(writer)
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ID + "_button")
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "button")
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "showCalendar('" + Me.ID + "')")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "18px")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%")
            writer.RenderBeginTag(HtmlTextWriterTag.Input)
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()
            If Me.DesignMode Then
                Return
            End If

            DateStyle.AddAttributesToRender(writer)
            If DateStyle.Width = Unit.Empty Then
                writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "200px")
            End If
            If DateStyle.BorderStyle = BorderStyle.NotSet Then
                writer.AddStyleAttribute("border", "1px outset")
            End If
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ID + "_date")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "absolute")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Visibility, "hidden")
            writer.RenderBeginTag(HtmlTextWriterTag.Div)
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%")
            writer.AddAttribute(HtmlTextWriterAttribute.Height, "100%")
            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0")
            writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0")
            writer.AddAttribute(HtmlTextWriterAttribute.Border, "0")
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderCollapse, "collapse")
            writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "hand")
            writer.RenderBeginTag(HtmlTextWriterTag.Table)

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            _titleStyle.AddAttributesToRender(writer)
            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "7")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0")
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%")
            writer.AddAttribute(HtmlTextWriterAttribute.Border, "0")
            writer.RenderBeginTag(HtmlTextWriterTag.Table)
            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            NextPrevStyle.AddAttributesToRender(writer)
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.AddAttribute(HtmlTextWriterAttribute.Title, "转到上一个月")
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "changemonth('" + ID + "',-1)")
            writer.RenderBeginTag(HtmlTextWriterTag.A)
            writer.Write("<")
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.AddAttribute(HtmlTextWriterAttribute.Align, "center")
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "70%")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ID + "_year")
            writer.RenderBeginTag(HtmlTextWriterTag.Span)
            writer.RenderEndTag()
            writer.Write("年")
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ID + "_month")
            writer.RenderBeginTag(HtmlTextWriterTag.Span)
            writer.RenderEndTag()
            writer.Write("月")
            writer.RenderEndTag()
            NextPrevStyle.AddAttributesToRender(writer)
            writer.AddAttribute(HtmlTextWriterAttribute.Align, "right")
            writer.RenderBeginTag(HtmlTextWriterTag.Td)
            writer.AddAttribute(HtmlTextWriterAttribute.Title, "转到下一个月")
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "changemonth('" + ID + "',1)")
            writer.RenderBeginTag(HtmlTextWriterTag.A)
            writer.Write(">")
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()
            writer.RenderEndTag()

            writer.RenderBeginTag(HtmlTextWriterTag.Tr)
            Dim ws As String() = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", _
            "星期六"}
            For Each s As String In ws
                DayHeaderStyle.AddAttributesToRender(writer)
                writer.AddAttribute(HtmlTextWriterAttribute.Scope, "col")
                If DayHeaderStyle.HorizontalAlign = HorizontalAlign.NotSet Then
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "center")
                End If
                writer.AddAttribute(HtmlTextWriterAttribute.Abbr, s)
                writer.RenderBeginTag(HtmlTextWriterTag.Th)
                writer.Write(s.Substring(2))
                writer.RenderEndTag()
            Next
            writer.RenderEndTag()
            writer.WriteLine("<!--end:header-->")

            Dim index As Integer = 0
            For i As Integer = 0 To 5

                writer.RenderBeginTag(HtmlTextWriterTag.Tr)
                For j As Integer = 0 To 6
                    If j = 0 OrElse j = 6 Then
                        WeekendDayStyle.AddAttributesToRender(writer)
                    Else
                        DayStyle.AddAttributesToRender(writer)
                    End If

                    If DayStyle.HorizontalAlign = HorizontalAlign.NotSet Then
                        writer.AddAttribute(HtmlTextWriterAttribute.Align, "center")
                    End If
                    writer.AddAttribute(HtmlTextWriterAttribute.Width, "14%")
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, ID + "_day" + index.ToString())
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "setvalue('" & ID & "'," & index & ")")
                    writer.RenderBeginTag(HtmlTextWriterTag.Td)
                    writer.RenderEndTag()
                    index += 1
                Next
                writer.RenderEndTag()
            Next

            writer.RenderEndTag()
            writer.RenderEndTag()
        End Sub
#End Region

#Region "script"
        Dim key As String = "dropdowncalendar_script"
        Dim script As String = "" & Chr(13) & "" & Chr(10) & "<script language =javascript>" & Chr(13) & "" & Chr(10) & "function showCalendar(calendar) " & Chr(13) & "" & Chr(10) & "{ " & Chr(13) & "" & Chr(10) & " var odate = document.getElementById(calendar+'_date'); " & Chr(13) & "" & Chr(10) & " if ( odate.style.visibility=='hidden' ){" & Chr(13) & "" & Chr(10) & " var y = document.getElementById(calendar+'_yeartext').value; " & Chr(13) & "" & Chr(10) & " var m = document.getElementById(calendar+'_monthtext').value;" & Chr(13) & "" & Chr(10) & " display( calendar,y,m); " & Chr(13) & "" & Chr(10) & " odate.style.visibility='visible';" & Chr(13) & "" & Chr(10) & " odate.style.display = 'block'; " & Chr(13) & "" & Chr(10) & " }else{" & Chr(13) & "" & Chr(10) & " odate.style.visibility='hidden';" & Chr(13) & "" & Chr(10) & " odate.style.display = 'none'; " & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "" & Chr(13) & "" & Chr(10) & "function changemonth(calendar,par)" & Chr(13) & "" & Chr(10) & "{ " & Chr(13) & "" & Chr(10) & " var omonth = document.getElementById(calendar+'_month');" & Chr(13) & "" & Chr(10) & " var oyear = document.getElementById(calendar+'_year'); " & Chr(13) & "" & Chr(10) & " var m = omonth.innerText;" & Chr(13) & "" & Chr(10) & " var y = oyear.innerText;" & Chr(13) & "" & Chr(10) & " m = parseInt(m)+par; " & Chr(13) & "" & Chr(10) & " if(parseInt(m)>12){ " & Chr(13) & "" & Chr(10) & " m = 1; " & Chr(13) & "" & Chr(10) & " y = parseInt(y)+1;" & Chr(13) & "" & Chr(10) & " } else if(parseInt(m)< 1) {" & Chr(13) & "" & Chr(10) & " m = 12; " & Chr(13) & "" & Chr(10) & " y = parseInt(y)-1;" & Chr(13) & "" & Chr(10) & " } " & Chr(13) & "" & Chr(10) & " display(calendar, y,m);" & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "" & Chr(13) & "" & Chr(10) & "function daysInMonth(month,year) " & Chr(13) & "" & Chr(10) & "{" & Chr(13) & "" & Chr(10) & " var ds=new Array(31,28,31,30,31,30,31,31,30,31,30,31);" & Chr(13) & "" & Chr(10) & " var n=ds[month];" & Chr(13) & "" & Chr(10) & " if(month==1&&year%4==0) ++n;" & Chr(13) & "" & Chr(10) & " return n;" & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "" & Chr(13) & "" & Chr(10) & "function display(calendar,year,month)" & Chr(13) & "" & Chr(10) & "{ " & Chr(13) & "" & Chr(10) & " var omonth = document.getElementById(calendar+'_month');" & Chr(13) & "" & Chr(10) & " var oyear = document.getElementById(calendar+'_year'); " & Chr(13) & "" & Chr(10) & " oyear.innerText = year;" & Chr(13) & "" & Chr(10) & " omonth.innerText = month; " & Chr(13) & "" & Chr(10) & " var start=new Date(year,month-1,1).getDay(); " & Chr(13) & "" & Chr(10) & " var days=daysInMonth(month-1,year); " & Chr(13) & "" & Chr(10) & " var pm = month-1,py = year; " & Chr(13) & "" & Chr(10) & " if ( pm == 0 ){" & Chr(13) & "" & Chr(10) & " pm = 12;" & Chr(13) & "" & Chr(10) & " py = year-1;" & Chr(13) & "" & Chr(10) & " } " & Chr(13) & "" & Chr(10) & " var pd=daysInMonth(pm-1,py); " & Chr(13) & "" & Chr(10) & " var day = calendar + '_day'; " & Chr(13) & "" & Chr(10) & " for(var i=0;i< start;i++){" & Chr(13) & "" & Chr(10) & " var td = document.getElementById(day+i);" & Chr(13) & "" & Chr(10) & " var d = pd-start+i+1;" & Chr(13) & "" & Chr(10) & " td.innerHTML='<font color = #808080>'+d+'</font>'; " & Chr(13) & "" & Chr(10) & " td.title=d+'日'; " & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & " for(var i= start+days; i< 42;i++){ " & Chr(13) & "" & Chr(10) & " var td = document.getElementById(day+i); " & Chr(13) & "" & Chr(10) & " var d = i-start-days+1; " & Chr(13) & "" & Chr(10) & " td.innerHTML='<font color = #808080>'+d+'</font>'; " & Chr(13) & "" & Chr(10) & " td.title=d+'日'; " & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & " for(var i=1;i<=days;i++){ " & Chr(13) & "" & Chr(10) & " var td = document.getElementById( day +(start+i-1));" & Chr(13) & "" & Chr(10) & " td.innerText=i; " & Chr(13) & "" & Chr(10) & " td.title=year+'年'+ month+'月'+i+'日'; " & Chr(13) & "" & Chr(10) & " } " & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "" & Chr(13) & "" & Chr(10) & "function validate(calendar)" & Chr(13) & "" & Chr(10) & "{" & Chr(13) & "" & Chr(10) & " var oyear = document.getElementById(calendar+'_yeartext'); " & Chr(13) & "" & Chr(10) & " var omonth = document.getElementById(calendar+'_monthtext');" & Chr(13) & "" & Chr(10) & " var oday = document.getElementById(calendar+'_daytext');" & Chr(13) & "" & Chr(10) & " var y = oyear.value;" & Chr(13) & "" & Chr(10) & " var m = omonth.value;" & Chr(13) & "" & Chr(10) & " var d = oday.value;" & Chr(13) & "" & Chr(10) & " var today = new Date();" & Chr(13) & "" & Chr(10) & " if ( isNaN(y)||y > 9999 || y< 1000){" & Chr(13) & "" & Chr(10) & " y = today.getFullYear();" & Chr(13) & "" & Chr(10) & " oyear.value = y;" & Chr(13) & "" & Chr(10) & " } " & Chr(13) & "" & Chr(10) & " if ( isNaN(m)|| m > 12 || y< 1){" & Chr(13) & "" & Chr(10) & " m = today.getMonth();" & Chr(13) & "" & Chr(10) & " omonth.value = m + 1;" & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & " if ( isNaN(d) || d < 1 || d > daysInMonth(m,y)){" & Chr(13) & "" & Chr(10) & " d = 10;" & Chr(13) & "" & Chr(10) & " oday.value = d;" & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "" & Chr(13) & "" & Chr(10) & "function setvalue(calendar,index)" & Chr(13) & "" & Chr(10) & "{" & Chr(13) & "" & Chr(10) & " var y = document.getElementById(calendar+'_year').innerText;" & Chr(13) & "" & Chr(10) & " var m = document.getElementById(calendar+'_month').innerText;" & Chr(13) & "" & Chr(10) & " var d = document.getElementById(calendar+'_day'+index).innerText; " & Chr(13) & "" & Chr(10) & " if ( parseInt(d) - 2 > index ) {" & Chr(13) & "" & Chr(10) & " m = parseInt(m)-1;" & Chr(13) & "" & Chr(10) & " if ( m == 0){" & Chr(13) & "" & Chr(10) & " m = 12;" & Chr(13) & "" & Chr(10) & " y = parseInt(y) - 1;" & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & " }else if (parseInt(d)+26<index ){" & Chr(13) & "" & Chr(10) & " m=parseInt(m)+1;" & Chr(13) & "" & Chr(10) & " if ( m == 13){" & Chr(13) & "" & Chr(10) & " m = 1;" & Chr(13) & "" & Chr(10) & " y = y + 1;" & Chr(13) & "" & Chr(10) & " }" & Chr(13) & "" & Chr(10) & " } " & Chr(13) & "" & Chr(10) & " document.getElementById(calendar+'_yeartext').value = y;" & Chr(13) & "" & Chr(10) & " document.getElementById(calendar+'_monthtext').value = m;" & Chr(13) & "" & Chr(10) & " document.getElementById(calendar+'_daytext').value = d;" & Chr(13) & "" & Chr(10) & " showCalendar(calendar); " & Chr(13) & "" & Chr(10) & "}" & Chr(13) & "" & Chr(10) & "</script>"
#End Region

    End Class
End Namespace